<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
    <title>ShellCheck: SC2014 – This will expand once before find runs, not per file found.</title>
    <link rel="stylesheet" href="css/bootstrap.min.css" />
  </head>
  <body style="margin-left: auto; margin-right: auto; max-width: 800px">
    <h1>SC2014 – ShellCheck Wiki</h1>
    <a href="https://github.com/koalaman/shellcheck/wiki/SC2014">See this page on GitHub</a>
    <p style="display: none"><a href="index.html">Sitemap</a></p>
    <hr />
    <h2 id="this-will-expand-once-before-find-runs-not-per-file-found">This
will expand once before find runs, not per file found.</h2>
<h3 id="problematic-code">Problematic code:</h3>
<div class="sourceCode" id="cb1"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb1-1"><a href="SC2014.html#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="fu">find</span> . <span class="at">-name</span> <span class="st">&#39;*.tar&#39;</span> <span class="at">-exec</span> tar xf {} <span class="at">-C</span> <span class="st">&quot;</span><span class="va">$(</span><span class="fu">dirname</span> {}<span class="va">)</span><span class="st">&quot;</span> <span class="dt">\;</span></span></code></pre></div>
<h3 id="correct-code">Correct code:</h3>
<div class="sourceCode" id="cb2"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb2-1"><a href="SC2014.html#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">find</span> . <span class="at">-name</span> <span class="st">&#39;*.tar&#39;</span> <span class="at">-exec</span> sh <span class="at">-c</span> <span class="st">&#39;tar xf &quot;$1&quot; -C &quot;$(dirname &quot;$1&quot;)&quot;&#39;</span> _ {} <span class="dt">\;</span></span></code></pre></div>
<h3 id="rationale">Rationale:</h3>
<p>Bash evaluates any command substitutions before the command they
feature in is executed. In this case, the command is <code>find</code>.
This means that <code>$(dirname {})</code> will run
<strong>before</strong> <code>find</code> runs, and not
<strong>while</strong> <code>find</code> runs.</p>
<p>To run shell code for each file, we can write a tiny script and
inline it with <code>sh -c</code>. We add <code>_</code> as a dummy
argument that becomes <code>$0</code>, and a filename argument that
becomes <code>$1</code> in the inlined script:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb3-1"><a href="SC2014.html#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="ex">$</span> sh <span class="at">-c</span> <span class="st">&#39;echo &quot;$1 is in $(dirname &quot;$1&quot;)&quot;&#39;</span> _ <span class="st">&quot;mydir/myfile&quot;</span></span>
<span id="cb3-2"><a href="SC2014.html#cb3-2" aria-hidden="true" tabindex="-1"></a><span class="ex">mydir/myfile</span> is in mydir</span></code></pre></div>
<p>This command can be executed by <code>find -exec</code>, with
<code>{}</code> as the filename argument. It executes shell which
interprets the inlined script once for each file. Note that the inlined
script is single quoted, again to ensure that the expansion does not
happen prematurely .</p>
<h3 id="exceptions">Exceptions:</h3>
<p>If you don't care (or if you prefer) that it's only expanded once,
like when dynamically selecting the executable to be used by all
invocations, you can ignore this message.</p>
    <hr />
    <p style='font-size: 80%'><a href="../index.html">ShellCheck</a> is a static analysis tool for shell scripts. This page is part of its documentation.</p>
  </body>
</html>


